home *** CD-ROM | disk | FTP | other *** search
- /*
- * Audio.cpp
- *
- * Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * FlasKMPEG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include <stdio.h>
- #include "Audio.h"
- #include ".\AC3\CAC3Dec.h"
-
-
-
- char *sAC3SampleFreq[4]={"48 Khz","44.1 Khz", "32 Khz","Unexpected"};
- int AC3Acmod[]={ 2, 1, 2, 3, 3, 4, 4, 5 };
- int AC3SampleFreq[4]={48000,44100,32000,0};
-
- struct TFrameSize framesize_table[] = {
- { 32 ,{64 ,69 ,96 } },
- { 32 ,{64 ,70 ,96 } },
- { 40 ,{80 ,87 ,120 } },
- { 40 ,{80 ,88 ,120 } },
- { 48 ,{96 ,104 ,144 } },
- { 48 ,{96 ,105 ,144 } },
- { 56 ,{112 ,121 ,168 } },
- { 56 ,{112 ,122 ,168 } },
- { 64 ,{128 ,139 ,192 } },
- { 64 ,{128 ,140 ,192 } },
- { 80 ,{160 ,174 ,240 } },
- { 80 ,{160 ,175 ,240 } },
- { 96 ,{192 ,208 ,288 } },
- { 96 ,{192 ,209 ,288 } },
- { 112 ,{224 ,243 ,336 } },
- { 112 ,{224 ,244 ,336 } },
- { 128 ,{256 ,278 ,384 } },
- { 128 ,{256 ,279 ,384 } },
- { 160 ,{320 ,348 ,480 } },
- { 160 ,{320 ,349 ,480 } },
- { 192 ,{384 ,417 ,576 } },
- { 192 ,{384 ,418 ,576 } },
- { 224 ,{448 ,487 ,672 } },
- { 224 ,{448 ,488 ,672 } },
- { 256 ,{512 ,557 ,768 } },
- { 256 ,{512 ,558 ,768 } },
- { 320 ,{640 ,696 ,960 } },
- { 320 ,{640 ,697 ,960 } },
- { 384 ,{768 ,835 ,1152 } },
- { 384 ,{768 ,836 ,1152 } },
- { 448 ,{896 ,975 ,1344 } },
- { 448 ,{896 ,976 ,1344 } },
- { 512 ,{1024 ,1114 ,1536 } },
- { 512 ,{1024 ,1115 ,1536 } },
- { 576 ,{1152 ,1253 ,1728 } },
- { 576 ,{1152 ,1254 ,1728 } },
- { 640 ,{1280 ,1393 ,1920 } },
- { 640 ,{1280 ,1394 ,1920 } }};
-
- static const int mpeg1_bitrate_table[3][15] = {
- { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
- { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }
- };
-
- static const int mpeg1_sampling_frequency[4] = { 44100, 48000, 32000 , 0 };
-
- static const int mpeg2_bitrate_table[3][15] = {
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
- };
-
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
-
- Audio::Audio(char *inputFile, int streamID, int subStreamID, int mode):CDemux()
- {
-
- SetInput(inputFile);
-
- Audio::streamID = streamID;
- Audio::subStreamID = subStreamID;
-
- resampler = NULL;
- decoded_samples_buffer = NULL;
- ResamplerBuffer = NULL;
- frameFIFO = NULL;
-
-
- Audio::sysClock=0;
- //file opened
- inp->SeekStream(0);
-
- //Detect Stream Type
- /* while ( (b->Show_Bits(16)!=AC3_SYNC_WORD) && (b->Show_Bits(12)!=MPEG_SYNC_WORD) )
- b->Flush_Buffer(1); */
- // Although this megamatic algorithm detectionroutines work in most cases
- // some startcode emulation cases have been found
- // for the time being, use stream_id as audio identifier
- if( subStreamID>= 0x80 && subStreamID <= 0x87 ){
- isAC3=true;
- isMPEG=false;
- }
- else if ((streamID >= 0xC0) && (streamID <= 0xDF)){
- isAC3=false;
- isMPEG=true;
- }
- else{
- isAC3=false;
- isMPEG=false;
- }
- GetAudioProperties();
- }
-
- Audio::~Audio()
- {
- }
-
- int Audio::GetAudioProperties()
- {
- TTimeSpan span;
- span.start=0;
- span.end = 0;
- ui8 *data;
- ui8 fscod, frmsizecode, acmod;
-
- // Create frame FIFO
- frameFIFO = new CAudFrameBuffer();
- ReadSpanInit();
-
- if(isAC3){
- while(ReadSpan(&span, 1*MPEG2_CLK_REF) ){
- if(frameFIFO->firstFrame==NULL)
- continue;
- else{
- //Take the first frame to retrieve audio info
- data = frameFIFO->firstFrame->data;
- fscod = (data[4] & 0xC0) >> 6;
- frmsizecode = (data[4] & 0x3F);
-
- sampleRate = AC3SampleFreq[fscod];
- strcpy(sSampleRate, sAC3SampleFreq[fscod]);
-
- sprintf(sBitRate,"%d Kbps", framesize_table[frmsizecode].bit_rate);
-
- //Update channels info
- acmod = (data[6] & 0xE0) >> 5;
- sprintf(sAudioMode,"%d Channels ", AC3Acmod[acmod]);
- break;
- }
- }
- }
- if(isMPEG){
- while(ReadSpan(&span, 1*MPEG2_CLK_REF) ){
- if(frameFIFO->firstFrame==NULL)
- continue;
- else{
- data = frameFIFO->firstFrame->data;
- long hdr;
- // Yay! A valid MPEG header! Parse it!
-
- // 0000F0FF 12 bits sync mark
- //
- // 00000800 1 bit version
- // 00000600 2 bits layer (3 = layer I, 2 = layer II, 1 = layer III)
- // 00000100 1 bit error protection (0 = enabled)
- //
- // 00F00000 4 bits bitrate_index
- // 000C0000 2 bits sampling_freq
- // 00020000 1 bit padding
- // 00010000 1 bit extension
- //
- // C0000000 2 bits mode (0=stereo, 1=joint stereo, 2=dual channel, 3=mono)
- // 30000000 2 bits mode_ext
- // 08000000 1 bit copyright
- // 04000000 1 bit original
- // 03000000 2 bits emphasis
- int is_mpeg2, layer, is_errorprotected, br_index, bitrate, sr_index, frequency;
-
- memcpy(&hdr, data, 4);
- //hdr = ((hdr&0xFF000000)>>24) | ((hdr&0x00FF0000)>>8) |
- // ((hdr&0x0000FF00)<< 8) | ((hdr&0x000000FF)<<24);
-
- is_mpeg2 = !(hdr & 0x00000800);
- layer = 4 - (hdr>>9)&3;
- is_errorprotected = !(hdr & 0x00000100);
- br_index = (hdr>>20)&15;
- bitrate = (is_mpeg2 ? mpeg2_bitrate_table : mpeg1_bitrate_table)[layer-1][br_index];
- sr_index = (hdr>>18)&3;
- frequency = mpeg1_sampling_frequency[sr_index];
-
- if (is_mpeg2)
- frequency>>=1;
-
- sampleRate = frequency;
-
- break;
- }
- }
- }
- delete frameFIFO;
- return 1;
- }
-
- //DO_AUDIO start
- int Audio::Start(int out_sFreq, i64 PTS, int audioMode){
- Audio::audioMode=audioMode;
-
-
- //AC.CreateCompressor();
-
- resampler=NULL;
- decoded_samples_buffer=NULL;
- ResamplerBuffer=NULL;
- frameFIFO =NULL;
- // read init
- frame_in_progress = false;
- aud_clk = 0;
- tot_n_samples = 0;
- StartReadLPES();
-
- if(audioMode==DO_AUDIO){
- ReadSpanInit();
- startPTS=PTS;
- justStarted=true;
- zeroSamplesToPad=0;
- PCM_PTS=PTS;
- sampleTime= (double)MPEG2_CLK_REF/((double)sampleRate);
-
- if(isAC3){
- AC3Dec = new CAC3Dec;
- AC3Dec->Init();
- }
- if(isMPEG){
-
- MPEGDec = new CMPEGDec;
- MPEGDec->Start();
- }
-
- frameFIFO = new CAudFrameBuffer();
- //Resampling stuff
- if(out_sFreq!=sampleRate){
- double factor= (double)out_sFreq/(double)sampleRate;
- decoded_samples_buffer= new CAsyncBuffer(this, PCM_1SECOND_SIZE, 1);
- resampler= new CResampler(factor, 2/*stereo*/,(CAsyncBuffer *)decoded_samples_buffer);
- resampler->ResampleFastStart();
- ResamplerBuffer= new CAsyncBuffer(resampler, 4096, 10);
- doResampling=true;
- }
- else{
- decoded_samples_buffer= new CAsyncBuffer((CDataSource *)this, PCM_1SECOND_SIZE,1);
- doResampling=false;
- }
- return 1;
- }
- return 0;
- }
- //DSC start
- int Audio::Start(char *inputFileName, int audioMode)
- {
- StartReadLPES();
- //eos
- resampler=NULL;
- decoded_samples_buffer=NULL;
- ResamplerBuffer=NULL;
- frameFIFO=NULL;
-
- frameFIFO = new CAudFrameBuffer();
- ReadSpanInit();
- char szTemp[1024];
- Audio::audioMode=audioMode;
- if(audioMode==DSC){
- justStarted=true;
- if(isAC3){
-
- strcpy(szTemp, inputFileName);
- strcat(szTemp, ".AC3");
- if((hOutputFile=fopen(szTemp,"wb"))==NULL)
- return 0;
- }
- else if(isMPEG){
- strcpy(szTemp, inputFileName);
- strcat(szTemp, ".mp2");
- if((hOutputFile=fopen(szTemp,"wb"))==NULL)
- return 0;
- }
- else
- return 0;
- //AlignFrame();
- justStarted=true;
- firstPTSfound=false;
- }
-
-
- return 1;
- }
-
- int Audio::Stop()
- {
- stopDecoder=true;
- justStarted=false;
-
- if(audioMode==DSC){
- //EndWritingFrame();
- //close file
- fclose(hOutputFile);
- }
- else if(audioMode==DO_AUDIO)
- {
- if(resampler){
- resampler->ResampleFastStop();
- delete resampler;
- resampler=NULL;
- }
- if(decoded_samples_buffer){
- delete decoded_samples_buffer;
- decoded_samples_buffer=NULL;
- }
- if(ResamplerBuffer){
- delete ResamplerBuffer;
- ResamplerBuffer=NULL;
- }
- if(isAC3)
- if(AC3Dec){
- delete AC3Dec;
- AC3Dec=NULL;
- }
- if(isMPEG)
- if(isMPEG){
- delete MPEGDec;
- MPEGDec=NULL;
- }
- }
- if(audioMode == DSC || audioMode==DO_AUDIO )
- if(frameFIFO){
- delete frameFIFO;
- frameFIFO=NULL;
- }
- return 1;
- }
- /*
- int Audio::GetAudio()
- {
- int bytesRead;
- if( (bytesRead=ReadStream( buffer, AUDIO_BUFFER_SIZE)) == AUDIO_BUFFER_SIZE){
- fwrite( buffer, 1, bytesRead, hOutputFile);
- return 1;
- }
- else{
- fwrite( buffer, 1, bytesRead, hOutputFile);
- goto end;
- }
-
- end:
- // decoderStopped=true;
- return 0;
-
- }
- */
-
- int Audio::SeekPTS(i64 PTS, i64 searchTop)
- {
- //We have to align the first frame with PTS greater or equal
- // to the given PTS, until searchTop byte of input stream
- //If the search was unsuccesful, return 0
- // return 1 otherwise
-
- if(isAC3){
- while(((b->Show_Bits(16)!=AC3_SYNC_WORD) || (b->PES.PTS<PTS)) && inp->GetStreamPos()<searchTop)
- b->Flush_Buffer(1);
- }
- else if(isMPEG){
- while(((b->Show_Bits(12)!=MPEG_SYNC_WORD) || (b->PES.PTS<PTS)) && inp->GetStreamPos()<searchTop)
- b->Flush_Buffer(1);
-
- }
- else return 0;
-
- if(inp->GetStreamPos()<searchTop) //Success
- // We should be at the right packet now
- return 1;
- else
- return 0;
- }
-
- int Audio::AlignFrame()
- {
-
- if(isAC3){
- while(b->Show_Bits(16)!=AC3_SYNC_WORD)
- b->Flush_Buffer(1);
- }
- else if(isMPEG){
- while((b->Show_Bits(12)!=MPEG_SYNC_WORD))
- b->Flush_Buffer(1);
-
- }
- else return 0;
-
- // We should be at the right packet now
- return 1;
- }
-
- //GetAudio Direct Stream Copy
- int Audio::GetAudioDSC(i64 PTS, i64 videoStreamPos)
- {
- TTimeSpan span;
-
- /* if(justStarted || firstPTSfound==false){
- if(justStarted)
- firstPTS=PTS;
- justStarted=false;
-
- if(!SeekPTS(firstPTS,videoStreamPos)){ //Align to the PTS with this PTS
- firstPTSfound=false;
- return 0;
- }
- else
- firstPTSfound=true;
-
- }*/
- //Parse packets up to videoStreamPos
-
- while(inp->GetStreamPos()<videoStreamPos){
- ReadSpan(&span, MPEG2_CLK_REF);
- while( frameFIFO->firstFrame ){
- fwrite( frameFIFO->firstFrame->data, frameFIFO->firstFrame->datasize , 1, hOutputFile);
- frameFIFO->RemoveFrame( frameFIFO->firstFrame );
- }
- }
-
-
- return 1;
-
- }
-
- int Audio::EndWritingFrame()
- { int my_bits=0;
- char buffer=0;
- if(isAC3){
- while((b->Show_Bits(16)!=AC3_SYNC_WORD) && b->eos==false ){
-
- buffer+= b->Get_Bits(1);
- buffer=buffer<<1;
- my_bits++;
- if(my_bits>=8){
- fwrite( &buffer, sizeof(buffer) , 1, hOutputFile);
- my_bits=0;
- buffer=0;
- }
- }
- }
- return 1;
- }
-
- int Audio::SeekAudio(i64 pos)
- {
- int val;
- val=inp->SetStreamPos(pos);
-
- return val;
- }
-
- int Audio::GetSamples(int frame, short **buffer, int nSamples)
- {/*
- if(justStarted){//Find first frame with PTS>PCM_PTS
- while(b->PES.PTS<PCM_PTS){
- b->Flush_Buffer(16); //Parse header
- AlignFrame();
- }
- justStarted=false;
- }
- */
- if(doResampling)
- ResamplerBuffer->ReadBuffer((char **)buffer, nSamples*4);
- else
- decoded_samples_buffer->ReadBuffer((char **)buffer, nSamples*4);
-
- //AC.Compress( *buffer, nSamples*2 );
- return 0;
- }
-
- #define ROUND(x) ( ((x-floor(x)) > 0.5) ? ceil(x) : floor(x) )
- int Audio::read(char *buffer){
-
- TTimeSpan span;
- span.start=0;
- span.end = 0;
-
- CAudioFrame *frame, *nextframe = NULL;
-
- ReadSpan(&span, 1*MPEG2_CLK_REF);
-
- i32 diff,span_samples_offset =0;
- ui32 frame_pcm_samples;
- i32 span_ptr = 0;
-
- // Update local audio clock, number of samples for this span,
- // and total number of samples.
- aud_clk += span.end - span.start;
- ui32 n_samples = ROUND((double)(aud_clk*sampleRate)/(double)MPEG2_CLK_REF) - tot_n_samples;
- tot_n_samples += n_samples;
-
-
- frame_pcm_samples = isAC3 ? 1536 : (isMPEG ? 1152 : 0) ;
- ui32 frame_duration = ((double)frame_pcm_samples/(double)sampleRate) * (double)MPEG2_CLK_REF;
-
- short *samples = (short *)buffer;
- memset(samples, 0, n_samples*4);
-
- OutputDebugString("span start");
- /*while( span_ptr < n_samples){*/
- if(frame_in_progress){
- memcpy( &samples[span_ptr*2], &temp_decoded_frame[temp_decoded_ptr*2], fip_remaining_bytes);
- span_ptr += (fip_remaining_bytes>>2);
- frame_in_progress = false;
- }
-
- if(frameFIFO->firstFrame){
- frame = frameFIFO->firstFrame;
- while( span_ptr < n_samples )
- {
- // we update nextframe here because it's likely to remove the
- // present frame during this iteration
- nextframe = frame->next;
- // If the frame doesn't fit in this span
- if( (span_ptr + frame_pcm_samples ) > n_samples){
- frame_in_progress=true;
- decodeFrame( frame, temp_decoded_frame);
- temp_decoded_ptr = n_samples - span_ptr;
- memcpy( &samples[span_ptr*2], temp_decoded_frame, temp_decoded_ptr*4);
-
- fip_remaining_bytes = (frame_pcm_samples*4) - (temp_decoded_ptr*4);
- frameFIFO->RemoveFrame(frame);
- span_ptr += temp_decoded_ptr;
- goto end;
- }
- if(frame->pInfo.hasPTS)
- {
- if( (frame->pInfo.PTS >= span.start) ){
- if(frame->pInfo.PTS > span.end)
- //frame out of the span
- goto end;
- // The frame starts inside this span
- /* if( (span.end - frame->pInfo.PTS) < frame_duration ){
- if(frame_in_progress){ //Oddly there is already a frame in progress. Remove it
- frameFIFO->RemoveFrame(frame);
- goto end;
- }
- //The frame doesn't completely fit into this span
- frame_in_progress=true;
-
- decodeFrame(frame, temp_decoded_frame);
-
- temp_decoded_ptr = n_samples - span_ptr;
- memcpy( &samples[span_ptr*2], temp_decoded_frame, temp_decoded_ptr*4);
-
- fip_remaining_bytes = (frame_pcm_samples*4) - (temp_decoded_ptr*4);
- frameFIFO->RemoveFrame(frame);
- span_ptr += temp_decoded_ptr;
-
- }
- else{*/
- span_samples_offset = ROUND((double)((frame->pInfo.PTS - span.start)*sampleRate)/(double)MPEG2_CLK_REF);
- /*if(span_samples_offset < span_ptr){
- //Something went wrong with this PTS. Put this frame
- // behind the decoded data if there is room for it
- if( (span_ptr+1536) <= n_samples ){
- AC3Dec->decodeFrame((short *)frame->data, &samples[span_ptr*2]);
- frameFIFO->RemoveFrame(frame);
- span_ptr+= 1536;
- }
- goto end;
- }*/
- //Handle small clock jitter
- diff=span_samples_offset-span_ptr;
- if( diff < 0 )
- span_samples_offset = span_ptr;
- else{
- diff = (diff>0) ? diff : -diff;
- if( diff < CLK_THRESHOLD )
- span_samples_offset = span_ptr;
- }
-
- decodeFrame(frame, &samples[span_samples_offset*2]);
-
- span_ptr = span_samples_offset + frame_pcm_samples;
- frameFIFO->RemoveFrame(frame);
- /*}*/
- }
- else{
- //The frame has a PTS previous to this span. ┐┐??
- //HACK
- // Decode the frame if the PTS from the current time
- // is just a little bit behind
- int clk_span = ((double)span_ptr/(double)sampleRate) * (double)MPEG2_CLK_REF;
- if( ((span.start+clk_span) - frame->pInfo.PTS) < CLK_THRESHOLD_SPAN){
- decodeFrame( frame, &samples[span_ptr*2] );
- span_ptr += frame_pcm_samples;
- }
- frameFIFO->RemoveFrame(frame);
- }
-
- }
- else{
- // decode frame right away
- decodeFrame( frame, &samples[span_ptr*2] );
- span_ptr += frame_pcm_samples;
- frameFIFO->RemoveFrame(frame);
- }
-
- end:
- if( nextframe==NULL )
- break;
- else
- frame = nextframe;
- }
- }
- //else There are no frames to be decoded in this span
- OutputDebugString("Audio Span End\n");
- /* }*/
- return n_samples*4;
- }
-
-
-
- int Audio::ReadSpan(TTimeSpan *span, i64 time)
- {
- ui64 nextSCR;
- int not_eof;
-
- not_eof=1;
- span->start = read_state.lastSCR;
- span->end = span->start;
- while( ((span->end - span->start) < time) && not_eof)
- {
- if( streamID==read_state.PES.pInfo.streamID &&
- subStreamID==read_state.PES.pInfo.subStreamID )
- ParseFrameData();
-
- not_eof=ReadLPES((unsigned char **)&read_state.PES.data, &read_state.PES.pInfo);
- if(!not_eof)
- break;
-
- span->end = read_state.PES.pInfo.SCR;
-
- // Update variables for next loop
- read_state.lastSCR = read_state.PES.pInfo.SCR;
- }
- return not_eof;
- }
-
- int inline Audio::RetrieveFrameData()
- {
- ui32 PES_bytes_left = read_state.PES.pInfo.payloadSize - read_state.in_ptr;
- ui8 *optr = &read_state.frame_data[read_state.out_ptr];
- ui8 *iptr = read_state.PES.data + read_state.in_ptr;
-
- if(read_state.frame_remaining_bytes <= PES_bytes_left){
- memcpy(optr, iptr, read_state.frame_remaining_bytes);
- // Add frame to the FIFO
- frameFIFO->AddFrame( read_state.frame_data,
- read_state.frame_size,
- &read_state.frame_pInfo);
- read_state.frame_in_course = false;
- read_state.in_ptr += read_state.frame_remaining_bytes;
- return 1;
- }
- else{
- memcpy(optr, iptr, PES_bytes_left);
- read_state.frame_in_course = true;
- read_state.out_ptr += PES_bytes_left;
- read_state.frame_remaining_bytes -= PES_bytes_left;
- return 0;
- }
- }
-
- void inline Audio::ParseFrameData()
- {
- ui8 *dataptr;
- ui32 headers_found = 0;
-
- read_state.in_ptr = 0;
-
- // take any possible audio frame and put it in the audio frame FIFO
- // we enter in this function when a PES of our ID was found
-
- // parse the frame in course
- if(read_state.frame_in_course){
- if(!RetrieveFrameData())
- return;
- }
- // wh
- while( read_state.in_ptr < read_state.PES.pInfo.payloadSize ){
- if(FindHeader(headers_found)){
- //An audio header was found
- headers_found++;
- if(!RetrieveFrameData())
- return;
- }
- else
- break;
- }
-
- }
-
-
- int Audio::ParseHeader(ui32 headers_found)
- {
-
-
- ui8 *data = read_state.PES.data;
- ui8 fscod;
- ui8 frmsizecode;
-
-
-
- if(isAC3){
- if( data[read_state.in_ptr]==0x0B && header_pos==0){
- read_state.header_in_course = true;
- header_pos = 1;
- //Handle presentation info
- if( (read_state.PES.pInfo.PTS != 0)
- && (headers_found==0) ){
- read_state.frame_pInfo.hasPTS = true;
- read_state.frame_pInfo.PTS
- = read_state.PES.pInfo.PTS;
- }
- else{
- read_state.frame_pInfo.hasPTS = false;
- read_state.frame_pInfo.PTS = 0;
- }
- return 0;
- }
-
- if( data[read_state.in_ptr]==0x77 && header_pos==1){
- read_state.header_in_course = true;
- header_pos = 2;
- return 0;
- }
- if( header_pos==2 ){
- read_state.header_in_course = true;
- hdr2 = data[read_state.in_ptr];
- header_pos = 3;
- return 0;
- }
- if( header_pos==3 ){
- read_state.header_in_course = true;
- hdr3 = data[read_state.in_ptr];
- header_pos = 4;
- return 0;
- }
- if( header_pos==4 ){
- read_state.header_in_course = true;
- fscod = (data[read_state.in_ptr] & 0xC0) >> 6;
- frmsizecode = (data[read_state.in_ptr] & 0x3F);
-
- // Check fscod and frmsizecode for valid parameters
- if( (fscod!=3) && (frmsizecode<38) ){
- read_state.frame_size = framesize_table[frmsizecode].frm_size[fscod]*2;
-
- //Reconstruct frame header
- read_state.frame_data[0] = 0x0B;
- read_state.frame_data[1] = 0x77;
- read_state.frame_data[2] = hdr2;
- read_state.frame_data[3] = hdr3;
- read_state.frame_data[4] = data[read_state.in_ptr];
-
-
-
- read_state.frame_remaining_bytes = read_state.frame_size - 5;
- read_state.out_ptr = 5;
- header_pos = 0;
- return 1;
- }
- }
- }
-
- if(isMPEG){
- if( data[read_state.in_ptr]==0xFF && header_pos==0){
- // MPEG audio header 0xFFF-
- read_state.header_in_course = true;
- header_pos = 1;
- //Handle presentation info
- if( (read_state.PES.pInfo.PTS != 0)
- && (headers_found==0) ){
- read_state.frame_pInfo.hasPTS = true;
- read_state.frame_pInfo.PTS
- = read_state.PES.pInfo.PTS;
- }
- else{
- read_state.frame_pInfo.hasPTS = false;
- read_state.frame_pInfo.PTS = 0;
- }
- mpeg_header[0] = data[read_state.in_ptr];
- return 0;
- }
- if( (data[read_state.in_ptr]&0xF8)==0xF8 && header_pos==1){
- // MPEG audio header
-
- mpeg_layer = (data[read_state.in_ptr]&0x06)>>1;
- if( mpeg_layer==3 ) //If the frame is Layer I
- mpeg_layer=1;
- else
- if( mpeg_layer==1 ) //If the frame is Layer III
- mpeg_layer=3;
- if( !mpeg_layer )
- header_pos = 0;
- else
- header_pos = 2;
-
- mpeg_header[1] = data[read_state.in_ptr];
-
- read_state.header_in_course = true;
- header_pos = 2;
- return 0;
- }
- if( header_pos==2 ){
- read_state.header_in_course = true;
-
- bit_rate_index = (data[read_state.in_ptr]&0xF0)>>4;
- if( bit_rate_index == 16 || bit_rate_index == 0 ){
- header_pos = 0;
- return 0;
- }
- bitrate = mpeg1_bitrate_table[mpeg_layer-1][bit_rate_index]*1000;
- sampling_frequency = (data[read_state.in_ptr]&0x0C)>>2;
- if( sampling_frequency == 3 ){
- header_pos = 0;
- return 0;
- }
- padding_bit = (data[read_state.in_ptr]&0x02)>>1;
- //Find number of slots and frame size
- if(mpeg_layer == 1){
- N = floor( (12 *(double)bitrate)/(double)mpeg1_sampling_frequency[sampling_frequency] );
- N = padding_bit ? (N+1) : N;
- read_state.frame_size = N*4;
- }
- else
- {
- N = floor( (144*(double)bitrate)/(double)mpeg1_sampling_frequency[sampling_frequency] );
- N = padding_bit ? (N+1) : N;
- read_state.frame_size = N;
- }
-
- mpeg_header[2] = data[read_state.in_ptr];
- memcpy( read_state.frame_data, mpeg_header, 3);
-
- read_state.frame_remaining_bytes = read_state.frame_size - 3;
- read_state.out_ptr = 3;
- header_pos = 0;
- return 1;
- }
- }
- header_pos = 0;
- read_state.header_in_course = false;
- return 0;
- }
-
- int Audio::FindHeader(ui32 headers_found)
- {
- bool header_found = false;
-
-
- //Search for an audio header from the current position
- while( read_state.in_ptr < read_state.PES.pInfo.payloadSize ){
- header_found = ParseHeader(headers_found);
- read_state.in_ptr++;
- if(header_found)
- break;
- }
-
- return header_found;
-
- }
- int Audio::ReadSpanInit()
- {
-
- //Force first time
- read_state.frame_in_course = false;
- read_state.header_in_course = false;
- read_state.frame_size = 0;
- read_state.frame_remaining_bytes = 0;
- read_state.lastSCR = 0;
- read_state.delta = 0;
- header_pos = 0;
- ReadLPES((unsigned char **)&read_state.PES.data, &read_state.PES.pInfo);
-
- return 1;
- }
-
- int Audio::decodeFrame(CAudioFrame *frame, short *pcm_samples)
- {
- if(isAC3){
- if(AC3Dec)
- AC3Dec->decodeFrame((short *)frame->data, frame->datasize,pcm_samples);
- return 1536;
- }
- if(isMPEG){
- if(isMPEG)
- MPEGDec->decodeFrame( (ui8 *)pcm_samples, frame->data, frame->datasize );
- return 1152;
- }
- return 0;
- }
-